AWS CDK で既存のリソースから Construct を取得する
概要
AWS CDK で既存のリソースから Construct を取得したい要件があると思います。例えば、すでにAWSに手動で構築してあるリソースや、別スタックでデプロイされているリソースなどです。CDK では便利な grant*
のメソッドがあり、これを使うことで面倒なIAMロール作成の手間を省くことができます。既存のリソースから grant*
のメソッドを使って、IAM ロールを作成したい要件もあるかと思います。 この記事では、別スタックでデプロイされている DynamoDB の ARN を取得し、別スタックから Lambda の環境変数にテーブル名を設定、さらに DynamoDB へのアクセス権限を付与する IAM ロールの設定を行うためのソースサンプルを記述します。
環境
cdk --version [cm-sato] 月 5/18 18:50:32 2020 1.39.0 (build 5d727c1)
DynamoDB スタック
以下のようなDynamoDBスタックを作成します。今回は sampleTable
というテーブルを作成しています。また、別のスタックで参照するために、ARN名をパラメーターストアに格納しています。
import * as cdk from '@aws-cdk/core'; import { Table, BillingMode, AttributeType } from '@aws-cdk/aws-dynamodb'; import { StringParameter } from '@aws-cdk/aws-ssm'; export class DynamoDBStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here const sampleTable = new Table(this, 'sampleTable', { billingMode: BillingMode.PAY_PER_REQUEST, partitionKey: { type: AttributeType.STRING, name: 'id', }, }); // テーブルARNをパラメータストアに登録する new StringParameter(this, 'SampleTableArn', { parameterName: 'SampleTableArn', stringValue: sampleTable.tableArn, }); } }
Lambda スタック
次に、Lambda 用のスタックを作成します。ここで、既存のリソースから Construct を取得します。CDK では既存のリソースから取得するために、from*Arn
メソッドが用意されています。 上記の DynamoDB スタックは先にデプロイされていることが前提となります。ここでは、パラメータストアから DynamoDB の Arn を取得し、そこから DynamoDB の Consturuct を取得しています。
import * as cdk from '@aws-cdk/core'; import { Function, Code, Runtime } from '@aws-cdk/aws-lambda'; import { StringParameter } from '@aws-cdk/aws-ssm'; import { Table } from '@aws-cdk/aws-dynamodb'; export class LambdaStack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // パラメータストアから値を取得する const tableArn = StringParameter.valueForStringParameter(this, 'SampleTableArn'); // 既存のテーブルを取得する const sampleTable = Table.fromTableArn(this, 'fromSampleTable', tableArn); const sampleFn = new Function(this, 'SampleFn', { code: Code.fromAsset('../handlers'), handler: 'sample.handler', runtime: Runtime.NODEJS_12_X, environment: { // 既存のテーブル情報からLambdaの環境変数にテーブル名を登録する SampleTableName: sampleTable.tableName } }); // 既存のテーブル情報からIAMロールを作成しLambda関数に設定する sampleTable.grantFullAccess(sampleFn); } }
デプロイ
#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from '@aws-cdk/core'; import { DynamoDBStack } from '../lib/dynamodb-stack'; import { LambdaStack } from '../lib/lambda-stack'; const app = new cdk.App(); new DynamoDBStack(app, 'DynamoDBStack'); new LambdaStack(app, 'LambdaStack');
cdk deploy DynamoDBStack cdk deploy LambdaStack
まとめ
小ネタ的な記事でした。CDK でスタックを分割する場合に、クロススタック参照にしてしまうと、スタック間が密結合になってしまい、参照元のスタックを更新できなくなるなどの問題があります。その解決策としてパラメーターストアと from*Arn
のメソッドを使って、スタック間を疎結合にするというような用途で使えると思います。